package com.cruising.backend.service.impl;

import com.cruising.backend.entity.ReportFiles;
import com.cruising.backend.entity.Reports;
import com.cruising.backend.entity.vo.PageVO;
import com.cruising.backend.entity.vo.ReportDetailVO;
import com.cruising.backend.mapper.ReportFilesMapper;
import com.cruising.backend.mapper.ReportsMapper;
import com.cruising.backend.service.ReportsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cruising.backend.utils.AliOssUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yezi
 * @since 2025-04-21
 */
@Service
@Slf4j
public class ReportsServiceImpl extends ServiceImpl<ReportsMapper, Reports> implements ReportsService {

    @Autowired
    private ReportsMapper reportsMapper;
    
    @Autowired
    private ReportFilesMapper reportFilesMapper;

    @Override
    public PageVO<Reports> getReports(Integer pageNum, Integer pageSize, String searchText, String startDate, String endDate, String sortType, String types, String labels, String role) {
        PageVO<Reports> pb = new PageVO<>();
        PageHelper.startPage(pageNum, pageSize);
        List<Reports> reports = reportsMapper.getReports(searchText, startDate, endDate,sortType,types,labels,role);
        Page<Reports> pag = (Page<Reports>) reports;
        pb.setTotal(pag.getTotal());
        pb.setItems(pag.getResult());
        return pb;
    }
    
    @Override
    public List<Reports> getReportsList(String searchText, String startDate, String endDate, String sortType, String types, String labels, String role) {
        // 直接调用Mapper查询方法获取所有符合条件的数据，不分页
        return reportsMapper.getReports(searchText, startDate, endDate, sortType, types, labels, role);
    }
    
    @Override
    public ReportDetailVO getReportDetailById(Integer reportId) {
        // 1. 获取举报信息
        Reports report = reportsMapper.selectById(reportId);
        if (report == null) {
            return null;
        }
        
        // 2. 获取相关文件列表
        List<ReportFiles> files = reportsMapper.getReportFiles(reportId);
        
        // 3. 封装数据并返回
        ReportDetailVO detailVO = new ReportDetailVO();
        detailVO.setReport(report);
        detailVO.setFiles(files);
        
        return detailVO;
    }
    
    @Override
    @Transactional
    public void saveReportWithFiles(Reports report, MultipartFile[] images, MultipartFile[] videos, MultipartFile[] otherFiles) throws Exception {
        // 1. 保存举报信息，获取自增ID
        log.info("保存举报信息：{}", report);
        reportsMapper.insert(report);
        Integer reportId = report.getReportId();
        
        // 2. 处理并保存图片文件
        if (images != null) {
            for (MultipartFile image : images) {
                if (image != null && !image.isEmpty()) {
                    String url = uploadFile(image, "images", reportId);
                    saveFileInfo(reportId, "image", image.getOriginalFilename(), url, (int) (image.getSize() / 1024));
                }
            }
        }
        
        // 3. 处理并保存视频文件
        if (videos != null) {
            for (MultipartFile video : videos) {
                if (video != null && !video.isEmpty()) {
                    String url = uploadFile(video, "videos", reportId);
                    saveFileInfo(reportId, "video", video.getOriginalFilename(), url, (int) (video.getSize() / 1024));
                }
            }
        }
        
        // 4. 处理并保存其他文件
        if (otherFiles != null) {
            for (MultipartFile file : otherFiles) {
                if (file != null && !file.isEmpty()) {
                    String url = uploadFile(file, "others", reportId);
                    saveFileInfo(reportId, "other", file.getOriginalFilename(), url, (int) (file.getSize() / 1024));
                }
            }
        }
    }
    
    /**
     * 上传文件到阿里云OSS
     * @param file 文件
     * @param folder 文件夹
     * @param reportId 举报ID
     * @return 文件URL
     */
    private String uploadFile(MultipartFile file, String folder, Integer reportId) throws Exception {
        // 生成唯一文件名
        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String fileName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;
        
        // 构建OSS存储路径
        String ossPath = "reports/" + reportId + "/" + folder + "/" + fileName;
        
        try {
            // 记录开始上传时间
            long startTime = System.currentTimeMillis();
            log.info("开始上传文件：{}，大小：{} KB", originalFilename, file.getSize() / 1024);
            
            // 上传文件到OSS
            String url = AliOssUtil.uploadFile(ossPath, file.getInputStream());
            
            // 记录上传耗时
            long endTime = System.currentTimeMillis();
            log.info("文件上传成功，URL：{}，耗时：{} 秒", url, (endTime - startTime) / 1000.0);
            
            return url;
        } catch (Exception e) {
            log.error("文件上传失败：{}，文件名：{}，大小：{} KB", e.getMessage(), originalFilename, file.getSize() / 1024, e);
            throw new Exception("文件 " + originalFilename + " 上传失败: " + e.getMessage());
        }
    }
    
    /**
     * 保存文件信息到数据库
     */
    private void saveFileInfo(Integer reportId, String fileType, String fileName, String filePath, Integer fileSize) {
        ReportFiles reportFile = new ReportFiles();
        reportFile.setReportId(reportId);
        reportFile.setFileType(fileType);
        reportFile.setFileName(fileName);
        reportFile.setFilePath(filePath);
        reportFile.setFileSize(fileSize);
        reportFile.setUploadTime(LocalDateTime.now());
        
        reportFilesMapper.insert(reportFile);
    }
}
